#include "album.h"
#include "album_common.h"
#include "file_utils.h"
#include "elog.h"
#include "elog_file.h"
#include "img_utils.h"
#include "timer_utils.h"
#include "sqlite3.h"

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include <iostream>
#include <filesystem>
#include <string>
#include <thread>
#include <functional>
#include <ctime>
#include <vector>
#include <algorithm>
#include <sstream>
#include <fstream>


namespace fs = std::filesystem;
using namespace std;

static sqlite3* album_db = nullptr;
static std::string album_db_filename = "/sdcard/DWARF_II/album.db";

Album::Album() {
    album_video_ = AlbumVideo();
    album_picture_ = AlbumPicture();
    album_burst_ = AlbumBurst();
    album_pano_ = AlbumPano();
    album_astro_ = AlbumAstro();
}

Album::~Album() {

}


int Album::init() {
    // 相册目录管理
    try {
        fs::create_directory(album_path);
        fs::create_directory(album_path + photograph_path);
        fs::create_directory(album_path + video_path);
        fs::create_directory(album_path + astro_path);
        fs::create_directory(album_path + panorama_path);
        fs::create_directory(album_path + burst_path);
        fs::create_directory(album_path + video_path + video_thumbnail_path);
        fs::create_directory(album_path + photograph_path + photo_thumbnail_path);

        log_i("album directories created succeessfully");
    } catch (const fs::filesystem_error& ex) {
        log_e("Error creating directories: %s", ex.what());
        return -1;
    }

    sqlite3_config(SQLITE_CONFIG_SERIALIZED); // 设置为Serialized Mode，线程安全模式

    initDB();

    thread organize_picture_t(&Album::organizePicture, this);
    organize_picture_t.detach();

    thread organize_burst_t(&Album::organizeBurst, this);
    organize_burst_t.detach();

    thread organize_panorama_t(&Album::organizePano, this);
    organize_panorama_t.detach();

    thread organize_astro_t(&Album::origanizeAstro, this);
    organize_astro_t.detach();

    thread organize_video_t(&Album::organizeVideo, this);
    organize_video_t.detach();

    return 0;
}

int Album::initDB() {
    char* errMsg = 0;
    int rc;

    // 打开数据库连接
    rc = sqlite3_open(album_db_filename.c_str(), &album_db);
    if (rc) {
        log_e("can not open database %s", sqlite3_errmsg(album_db));
        return -1;
    } else {
        log_i("open database successfully");
    }

    
    album_picture_.createPictureInfoTable(album_db);
    album_burst_.createBurstInfoTable(album_db);
    album_pano_.createPanoInfoTable(album_db);
    album_video_.createVideoInfoTable(album_db);
    album_astro_.createAstroInfoTable(album_db);

    return 0;
}

std::vector<AlbumAllInfo> Album::queryAlbumAllInfoByTime() {
    log_i("queryAlbumAllInfoByTime");
    std::vector<AlbumAllInfo> result;

    if (!album_db) {
        log_e("The database connection is not initialized");
        return result;
    }

    std::string sql = R"(
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, NULL, NULL, dec, ra, target, binning, format, exp_time, gain, shotsToTake, shotsTaken, shotsStacked, ircut, media_type FROM astroInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM pictureInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, NULL, file_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM burstInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, duration, width, height, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM videoInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, row, col, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM panoramaInfo
        ORDER BY modification_time DESC;
    )";

    sqlite3_stmt* stmt;
    
    int rc = sqlite3_prepare_v2(album_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("Can not prepare SQL: %s", sqlite3_errmsg(album_db));
        return result;
    }
    
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AlbumAllInfo info;
        
        if (sqlite3_column_text(stmt, 0) != nullptr) {
            info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
            // log_i("file_path = %s", info.common_info.file_path.c_str());
        }
        info.common_info.modification_time = sqlite3_column_int64(stmt, 1);
        // log_i("modification_time = %d", info.common_info.modification_time);
        
        if (sqlite3_column_text(stmt, 2) != nullptr) {
            info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
        }
        if (sqlite3_column_text(stmt, 3) != nullptr) {
            info.common_info.file_size = sqlite3_column_int64(stmt, 3);
        }
        info.burst_unique_info.file_count = sqlite3_column_int(stmt, 4);
        info.video_unique_info.duration = sqlite3_column_int(stmt, 5);
        info.video_unique_info.width = sqlite3_column_int(stmt, 6);
        info.video_unique_info.height = sqlite3_column_int(stmt, 7);
        info.pano_unique_info.row = sqlite3_column_int(stmt, 8);
        info.pano_unique_info.col = sqlite3_column_int(stmt, 9);
        
        if (sqlite3_column_text(stmt, 10) != nullptr) {
            info.astro_unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        }
        
        if (sqlite3_column_text(stmt, 11) != nullptr) {
            info.astro_unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 11));
        }
        
        if (sqlite3_column_text(stmt, 12) != nullptr) {
            info.astro_unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 12));
        }
        
        if (sqlite3_column_text(stmt, 13) != nullptr) {
            info.astro_unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 13));
        }
        
        if (sqlite3_column_text(stmt, 14) != nullptr) {
            info.astro_unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 14));
        }
        
        if (sqlite3_column_text(stmt, 15) != nullptr) {
            info.astro_unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        }
        info.astro_unique_info.gain = sqlite3_column_int(stmt, 16);
        info.astro_unique_info.shotsToTake = sqlite3_column_int(stmt, 17);
        info.astro_unique_info.shotsTaken = sqlite3_column_int(stmt, 18);
        info.astro_unique_info.shotsStacked = sqlite3_column_int(stmt, 19);
        
        if (sqlite3_column_text(stmt, 20) != nullptr) {
            info.astro_unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 20));
        }

        info.common_info.media_type = sqlite3_column_int(stmt, 21);

        result.push_back(info);
    }

    return result;
}


std::vector<AlbumAllInfo> Album::queryAlbumAllInfoByTime(int page_index, int page_size) {
    std::vector<AlbumAllInfo> result;

    if (!album_db) {
        log_e("The database connection is not initialized");
        return result;
    }

     std::string sql = R"(
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, NULL, NULL, dec, ra, target, binning, format, exp_time, gain, shotsToTake, shotsTaken, shotsStacked, ircut, media_type FROM astroInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM pictureInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, NULL, file_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM burstInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, duration, width, height, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM videoInfo
        UNION ALL
        SELECT file_path, modification_time, thumbnail_path, file_size, NULL, NULL, NULL, NULL, row, col, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, media_type FROM panoramaInfo
        ORDER BY modification_time DESC LIMIT ? OFFSET ?;
    )";


    sqlite3_stmt* stmt;

    int rc = sqlite3_prepare_v2(album_db, sql.c_str(), -1, &stmt, nullptr);
    if (rc != SQLITE_OK) {
        log_e("can not prepare sql: %s", sqlite3_errmsg(album_db));
        return result;
    }

    int offset = page_index * page_size;
    sqlite3_bind_int(stmt, 1, page_size);
    sqlite3_bind_int(stmt, 2, offset);

    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        AlbumAllInfo info;
        
        if (sqlite3_column_text(stmt, 0) != nullptr) {
            info.common_info.file_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
            // log_i("file_path = %s", info.common_info.file_path.c_str());
        }
        info.common_info.modification_time = sqlite3_column_int64(stmt, 1);
        // log_i("modification_time = %d", info.common_info.modification_time);
        
        if (sqlite3_column_text(stmt, 2) != nullptr) {
            info.common_info.thumbnail_path = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
        }
        if (sqlite3_column_text(stmt, 3) != nullptr) {
            info.common_info.file_size = sqlite3_column_int64(stmt, 3);
        }
        info.burst_unique_info.file_count = sqlite3_column_int(stmt, 4);
        info.video_unique_info.duration = sqlite3_column_int(stmt, 5);
        info.video_unique_info.width = sqlite3_column_int(stmt, 6);
        info.video_unique_info.height = sqlite3_column_int(stmt, 7);
        info.pano_unique_info.row = sqlite3_column_int(stmt, 8);
        info.pano_unique_info.col = sqlite3_column_int(stmt, 9);
        
        if (sqlite3_column_text(stmt, 10) != nullptr) {
            info.astro_unique_info.dec = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 10));
        }
        
        if (sqlite3_column_text(stmt, 11) != nullptr) {
            info.astro_unique_info.ra = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 11));
        }
        
        if (sqlite3_column_text(stmt, 12) != nullptr) {
            info.astro_unique_info.target = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 12));
        }
        
        if (sqlite3_column_text(stmt, 13) != nullptr) {
            info.astro_unique_info.binning = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 13));
        }
        
        if (sqlite3_column_text(stmt, 14) != nullptr) {
            info.astro_unique_info.format = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 14));
        }
        
        if (sqlite3_column_text(stmt, 15) != nullptr) {
            info.astro_unique_info.exp_time = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 15));
        }
        info.astro_unique_info.gain = sqlite3_column_int(stmt, 16);
        info.astro_unique_info.shotsToTake = sqlite3_column_int(stmt, 17);
        info.astro_unique_info.shotsTaken = sqlite3_column_int(stmt, 18);
        info.astro_unique_info.shotsStacked = sqlite3_column_int(stmt, 19);
        
        if (sqlite3_column_text(stmt, 20) != nullptr) {
            info.astro_unique_info.ircut = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 20));
        }

        info.common_info.media_type = sqlite3_column_int(stmt, 21);

        result.push_back(info);
    }

    sqlite3_finalize(stmt);

    return result;
}

/*
    普通照片整理
    1. 整理旧固件相册文件,写入信息
    2. 同步本地文件信息到数据库，加入数据库里面没有的文件
    3. 更新数据库，删除本地没有的文件信息
*/
int Album::organizePicture() {
    std::string src_dir = sdcard_path;
    std::string dest_dir = album_path + photograph_path;
    std::string prefix = "DWARF_";
    std::string extension = ".jpeg";

    // 整理旧固件相册文件,写入信息
    try {
        for (const auto& entry : fs::directory_iterator(src_dir)) {
            if (entry.is_regular_file()) {
                const std::string& filename = entry.path().filename().string();
                if (startsWith(filename, prefix) && entry.path().extension() == extension) {
                    std::string current_img_path = entry.path().string();
                    PictureInfo picture_info;
                    std::string dest_path = dest_dir + filename;
                    std::string dest_thumbnail_path = dest_dir + photo_thumbnail_path + filename;

                    picture_info.common_info.modification_time = getFileModifiedTime(current_img_path);
                    picture_info.common_info.file_size = getFileSizeInt(current_img_path);
                    if (!fs::exists(dest_thumbnail_path)) {
                        imageDownsample(current_img_path, dest_thumbnail_path, album_thumbnail_width, album_thumbnail_height);
                    }
                    
                    // 移动文件
                    fs::rename(entry.path(), dest_path);
                    log_i("Moved file: %s", filename.c_str());

                    picture_info.common_info.file_path = dest_path;
                    if (fs::exists(dest_thumbnail_path)) {
                        picture_info.common_info.thumbnail_path = dest_thumbnail_path;
                    } else {
                        picture_info.common_info.thumbnail_path = dest_path;
                    }
                    
                    picture_info.common_info.width = 0;
                    picture_info.common_info.height = 0;
                    picture_info.common_info.media_type = MEDIA_PICTURE;
                    album_picture_.printPictureInfo(picture_info);
                    album_picture_.insertPictureInfo(picture_info);
                }
            }
        }
    } catch (const fs::filesystem_error& ex) {
        log_e("Error moving files: %s", ex.what());
    }

    // 同步本地文件信息到数据库
    for (const auto& entry : fs::directory_iterator(dest_dir)) {
        if (entry.is_regular_file()) {
            const std::string& filename = entry.path().filename().string();
            if (startsWith(filename, prefix) && (entry.path().extension() == ".jpg" || entry.path().extension() == ".jpeg")) {
                std::string current_img_path = entry.path().string();
                std::string dest_path = dest_dir + filename;
                std::string thumbnail_path = album_path + photograph_path + photo_thumbnail_path + filename;
                if (getImageSize(thumbnail_path).width < album_thumbnail_width)
                    imageDownsample(dest_path, thumbnail_path, album_thumbnail_width, album_thumbnail_height);
                std::vector<PictureInfo> find_picture_info = album_picture_.queryPictureInfoByFilepath(dest_path);
                if (!find_picture_info.empty()) {
                    continue;
                } else {
                    album_picture_.updatePicture(dest_path);
                }  
            }
        }
    }

    // 更新数据库
    std::vector<PictureInfo> picture_info_list = album_picture_.queryAllPictureInfo();
    for (const auto& info : picture_info_list) {
        if (!fs::exists(info.common_info.file_path)) {
            album_picture_.deletePictureInfo(info.common_info.file_path);
        }
    }

    return 0;
}

/*
    连拍整理
    1. 整理旧固件相册文件,写入信息
    2. 同步本地文件信息到数据库，加入数据库里面没有的文件
    3. 更新数据库，删除本地没有的文件信息
*/
int Album::organizeBurst() {
    std::string src_dir = sdcard_path;
    std::string dest_dir = album_path + burst_path;
    std::string prefix = "DWARF_";
    std::vector<std::string> exclusions = { "RAW", "GOTO", "DARK", "PANORAMA" };

    try {
        for (const auto& entry : fs::directory_iterator(src_dir)) {
            if (entry.is_directory()) {
                // 获取源文件夹名称
                const std::string& dirname = entry.path().filename().string();
                if (startsWith(dirname, prefix) && !containsAny(dirname, exclusions) && !(dirname == "DWARF_II")) {
                    BurstInfo burst_info;
                    // 获取源文件夹路径
                    std::string src_burst_path = entry.path().string();
                    // 获取目标文件夹路径
                    std::string dest_burst_path = dest_dir + dirname;

                    burst_info.common_info.modification_time = getFileModifiedTime(src_burst_path);
                    burst_info.unique_info.file_count = countFilesWithExtension(src_burst_path, ".jpeg");
                    burst_info.common_info.width = 0;
                    burst_info.common_info.height = 0;
                    burst_info.common_info.media_type = MEDIA_BURST;

                    // 移动当前文件夹
                    fs::rename(entry.path(), dest_burst_path);
                    log_i("Moved directory: %s", dirname.c_str());

                    std::string first_file_path = getFirstFileWithExtension(dest_burst_path , ".jpeg");
                    std::string dest_thumbnail_path;
                    if (fs::exists(first_file_path)) {
                        dest_thumbnail_path = dest_burst_path + "/burst_thumbnail.jpg";
                        burst_info.common_info.file_path = first_file_path;
                        imageDownsample(first_file_path, dest_thumbnail_path, album_thumbnail_width, album_thumbnail_height);
                    }

                    if (fs::exists(dest_thumbnail_path))
                        burst_info.common_info.thumbnail_path = dest_thumbnail_path;
                    album_burst_.printBurstInfo(burst_info);
                    album_burst_.insertBurstInfo(burst_info);
                }
            }
        }
    } catch (const fs::filesystem_error& ex) {
        log_e("Error moving directories: %s", ex.what());
    }

    // 同步本地文件信息到数据库
    for (const auto& entry : fs::directory_iterator(dest_dir)) {
        if (entry.is_directory()) {
            // 获取文件夹名称
            const std::string& dirname = entry.path().filename().string();
            if (startsWith(dirname, prefix) && !containsAny(dirname, exclusions)) {
                // 获取目标文件夹路径
                std::string dest_burst_path = dest_dir + dirname;
                album_burst_.updateBurst(dest_burst_path);
            }
        }
    }

    // 更新数据库
    std::vector<BurstInfo> burst_info_list = album_burst_.queryAllBurstInfo();
    for (const auto& info : burst_info_list) {
        if (!fs::exists(info.common_info.file_path)) {
            album_burst_.deleteBurstInfo(info.common_info.file_path);
        }
    }

    return 0;
}

/*
   全景整理
    1. 整理旧固件相册文件,生成全景缩略图
    2. 同步本地文件信息到数据库，加入数据库里面没有的文件
    3. 更新数据库，删除本地没有的文件信息
*/
int Album::organizePano() {
    string src_dir = sdcard_path;
    string dest_dir = album_path + panorama_path;
    string prefix = "DWARF_PANORAMA_";
    
    // 整理旧固件相册文件,生成全景缩略图
    try {
        for (const auto& entry : fs::directory_iterator(src_dir)) {
            if (entry.is_directory()) {
                // 获取源文件夹名称
                const std::string& dirname = entry.path().filename().string();
                if (startsWith(dirname, prefix)) {
                    PanoInfo pano_info;
                    // 获取目标文件夹路径
                    std::string dest_pano_path = dest_dir  + dirname;

                    // 移动当前文件夹
                    fs::rename(entry.path(), dest_pano_path);
                    log_i("Moved directory: %s", dirname.c_str());
                }
            }
        }
    } catch (const fs::filesystem_error& ex) {
        log_e("Error moving directories: %s", ex.what());
    }

    // 同步本地文件
    for (const auto& entry : fs::directory_iterator(dest_dir)) {
        if (entry.is_directory()) {
            // 获取源文件夹名称
            const std::string& dirname = entry.path().filename().string();
            if (startsWith(dirname, prefix)) {
                PanoInfo pano_info;
                // 获取目标文件夹路径
                std::string dest_pano_path = dest_dir  + dirname;
                album_pano_.updatePano(dest_pano_path, 0, 0);
            }
        }
    }

    // 更新数据库
    std::vector<PanoInfo> pano_info_list = album_pano_.queryAllPanoInfo();
    for (const auto& info : pano_info_list) {
        if (!fs::exists(info.common_info.file_path)) {
            album_pano_.deletePanoInfo(info.common_info.file_path);
        }
    }

    return 0;
}

/*
    天文整理
    1. 整理旧固件相册文件,生成天文缩略图
    2. 同步本地文件信息到数据库，加入数据库里面没有的文件
    3. 更新数据库，删除本地没有的文件信息
*/
int Album::origanizeAstro() {
    std::string src_dir = sdcard_path;
    std::string dest_dir = album_path + astro_path;
    std::string prefix_goto = "DWARF_GOTO";
    std::string prefix_raw = "DWARF_RAW";
    std::string prefix_dark = "DWARF_DARK";

    deleteDirectoriesWithPrefix(src_dir, prefix_goto);
    moveDirectoriesWithPrefix(src_dir, dest_dir, prefix_dark);
    moveDirectoriesWithPrefix(src_dir, dest_dir, prefix_raw);

    // 生成缩略图整理旧固件相册文件,生成天文缩略图
    try {
        for (const auto& entry : fs::directory_iterator(dest_dir)) {
            if (entry.is_directory()) {
                // 获取源文件夹名称
                const std::string& dirname = entry.path().filename().string();

                if (startsWith(dirname, prefix_raw)) {
                    std::string dest_path = entry.path().string();
                    album_astro_.updateAstro(dest_path);
                }
            } 
        }
    } catch (const fs::filesystem_error& ex) {
        log_e("Error moving directories: %s", ex.what());
    }

    // 更新数据库
    std::vector<AstroInfo> astro_info_list = album_astro_.queryAllAstroInfo();
    for (const auto& info : astro_info_list) {
        if (!fs::exists(info.common_info.file_path)) {
            album_astro_.deleteAstroInfo(info.common_info.file_path);
        }
    }

    // astro_info_list = album_astro_.queryAllAstroInfo();
    // for (const auto& info : astro_info_list) {
    //     album_astro_.printAstroInfo(info);
    // }

    return 0;
}

/*
    视频整理
    1. 整理旧固件相册文件,生成视频缩略图,写入信息
    2. 同步本地文件信息到数据库
    3. 更新数据库
*/
int Album::organizeVideo() {
    std::string src_dir = sdcard_path;
    std::string dest_dir = album_path + video_path;
    std::string thumbnail_path = album_path + video_path + video_thumbnail_path;
    std::string prefix = "DWARF_";
    std::string extension = ".mp4";

    // 生成视频缩略图
    try {
        for (const auto& entry : fs::directory_iterator(src_dir)) {
            if (entry.is_regular_file()) {
                const string& file_name = entry.path().filename().string();
                if (startsWith(file_name, prefix) && entry.path().extension() == extension) {
                    string current_video_path = entry.path().string();
                    fs::path videoFilePath(entry.path());
                    string img_path_temp = src_dir + videoFilePath.stem().string() + "_temp" + ".jpg";
                    string img_path = src_dir + videoFilePath.stem().string() + ".jpg";
                    string img_thumbnail_path = thumbnail_path + videoFilePath.stem().string() + ".jpg";
                    string video_dest_path = dest_dir + videoFilePath.stem().string() + extension;
                    VideoInfo video_info;

                    album_video_.getVideoInfo(current_video_path, video_info);
                    video_info.common_info.modification_time = getFileModifiedTime(current_video_path);
                    video_info.common_info.file_size = getFileSizeInt(current_video_path); 

                    album_video_.getFrameFromvideo(entry.path().string(), img_path_temp);

                    if (fs::exists(img_path_temp)) {
                        imageDownsample(img_path_temp, img_path, album_thumbnail_width, album_thumbnail_height);
                    }

                    deleteFile(img_path_temp);
                    // 移动文件
                    log_i("img_path = %s", img_path.c_str());
                    log_i("img_thumbnail_path = %s", img_thumbnail_path.c_str());
                    fs::rename(img_path, img_thumbnail_path);
                    log_i("Moved file: %s", img_path.c_str());
                    fs::rename(entry.path(), video_dest_path);
                    log_i("Moved file: %s", video_dest_path.c_str());
                    system("sync");

                    video_info.common_info.file_path = video_dest_path;
                    video_info.common_info.thumbnail_path = img_thumbnail_path;
                    video_info.common_info.media_type = MEDIA_VIDEO;
                    album_video_.printVideoInfo(video_info);

                    album_video_.insertVideoInfo(video_info);
                }
            }
        }
    } catch (const fs::filesystem_error& ex) {
        log_e("Error moving files: %s", ex.what());
    }

    // 同步本地文件信息到数据库
    for (const auto& entry : fs::directory_iterator(dest_dir)) {
        if (entry.is_regular_file()) {
            const string& filename = entry.path().filename().string();
            if (entry.path().extension() == extension) {
                string current_video_path = entry.path().string();
                fs::path video_file_path(entry.path());
                string img_thumbnail_path = thumbnail_path + video_file_path.stem().string() + ".jpg";

                if (!fs::exists(img_thumbnail_path)) {
                    album_video_.getFrameFromvideo(entry.path().string(), img_thumbnail_path);
                }

                std::vector<VideoInfo> find_video_info = album_video_.queryVideoInfoByFilepath(current_video_path);
                if (!find_video_info.empty()) {
                    continue;
                } else {
                    album_video_.updateVideo(current_video_path);
                }
            }
        }
    }

    // 更新数据库
    std::vector<VideoInfo> video_info_list = album_video_.queryAllVideoInfo();
    for (const auto& info : video_info_list) {
        if (!fs::exists(info.common_info.file_path)) {
            album_video_.deleteVideoInfo(info.common_info.file_path);
        }
    }

    return 0;
}